﻿

using System.Text.Json;
using System.Text.Json.Serialization;

namespace SubstrateTrackingDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 1. 创建事件集合
            var trackingId = Guid.NewGuid();
            var events = new List<SubstrateTrackingEvent>
            {
                // Foup 开启事件（记录所有晶圆槽状态）
                new FoupOpenEvent {
                    TrackingId = trackingId,
                    Foup = 1,
                    Slots = new[] {
                        new WaferState { State = WaferStatus.Empty },
                        new WaferState { State = WaferStatus.Processing }
                    }
                },

                // 晶圆传输开始
                new WaferTransferStartEvent { TrackingId = trackingId },

                // 具体传输动作
                new WaferTransferEvent {
                    TrackingId = trackingId,
                    Foup = 1,
                    Slot = 2,
                    From = WaferLocation.LoadPort,
                    To = WaferLocation.ProcessChamber
                },

                // 手动操作示例
                new ManuallySetLocationEvent {
                    TrackingId = Guid.NewGuid(), // 独立事件
                    Foup = 2,
                    Slot = 5,
                    Location = WaferLocation.CleanRoom,
                    IsDelete = false
                }
            };

            // 2. 序列化为 JSON（需要配置多态支持）
            var options = new JsonSerializerOptions
            {
                WriteIndented = true 
            };

            string json = JsonSerializer.Serialize(events, options);
            Console.WriteLine("=== 序列化后的 JSON ===");
            Console.WriteLine(json);

            // 3. 反序列化
            var deserializedEvents = JsonSerializer.Deserialize<List<SubstrateTrackingEvent>>(json, options);

            // 4. 处理事件
            //var logger = LoggerFactory.Create(b => b.AddConsole()).CreateLogger<Program>();
            var tracker = new SubstrateTracker();

            foreach (var evt in deserializedEvents)
            {
                tracker.HandleEvent(evt);
            }

            Console.ReadKey();
        }

        // 模拟业务处理类
        public class SubstrateTracker
        {

            public SubstrateTracker()
            {
            }

            public void HandleEvent(SubstrateTrackingEvent evt)
            {
                Console.WriteLine($"处理事件 [{evt.GetType().Name}] ID:{evt.Id}");

                // 根据事件类型路由处理
                switch (evt)
                {
                    case FoupOpenEvent e:
                        HandleFoupOpen(e);
                        break;
                    case WaferTransferEvent e:
                        HandleWaferTransfer(e);
                        break;
                    case ManuallySetLocationEvent e:
                        HandleManualLocation(e);
                        break;
                        // 其他事件类型处理...
                }
            }

            private void HandleFoupOpen(FoupOpenEvent evt)
            {
                Console.WriteLine($"Foup {evt.Foup} 开启，初始化槽位状态");
                // 更新系统状态...
            }

            private void HandleWaferTransfer(WaferTransferEvent evt)
            {
                Console.WriteLine($"晶圆转移: Foup {evt.Foup} Slot {evt.Slot} " +
                                     $"{evt.From} => {evt.To}");
                // 更新晶圆位置...
            }

            private void HandleManualLocation(ManuallySetLocationEvent evt)
            {
                var action = evt.IsDelete ? "删除" : "设置";
                Console.WriteLine($"[人工操作] {action} Foup {evt.Foup} " +
                                  $"Slot {evt.Slot} 位置为 {evt.Location}");
            }
        }
    }

    [JsonPolymorphic]
    [JsonDerivedType(typeof(FoupOpenEvent), typeDiscriminator: "FoupOpen")]
    [JsonDerivedType(typeof(FoupClosedEvent), typeDiscriminator: "FoupClosed")]
    [JsonDerivedType(typeof(FoupErrorEvent), typeDiscriminator: "FoupError")]
    [JsonDerivedType(typeof(WaferTransferStartEvent), typeDiscriminator: "WaferTransferStart")]
    [JsonDerivedType(typeof(WaferTransferEndEvent), typeDiscriminator: "WaferTransferEnd")]
    [JsonDerivedType(typeof(WaferStateChangedEvent), typeDiscriminator: "WaferStateChanged")]
    [JsonDerivedType(typeof(WaferTransferErrorEvent), typeDiscriminator: "WaferTransferError")]
    [JsonDerivedType(typeof(WaferTransferEvent), typeDiscriminator: "WaferTransfer")]
    [JsonDerivedType(typeof(WaferSwapEvent), typeDiscriminator: "WaferSwap")]
    [JsonDerivedType(typeof(ManuallySetLocationEvent), typeDiscriminator: "ManuallySetLocation")]
    [JsonDerivedType(typeof(ManuallyCreateWaferEvent), typeDiscriminator: "ManuallyCreateWafer")]
    [JsonDerivedType(typeof(ManuallyDeleteWaferEvent), typeDiscriminator: "ManuallyDeleteWafer")]
    [JsonDerivedType(typeof(ManuallyModifyWaferEvent), typeDiscriminator: "ManuallyModifyWafer")]

    public abstract class SubstrateTrackingEvent
    {
        // auto-generated
        public string Id { get; set; } = "";

        public required Guid TrackingId { get; set; }
    }

    public class FoupOpenEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public required WaferState[] Slots { get; set; }
    }

    public class FoupClosedEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }
    }

    public class FoupErrorEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public string Message { get; set; } = "";
    }

    public class WaferTransferStartEvent : SubstrateTrackingEvent
    {
    }

    public class WaferTransferEndEvent : SubstrateTrackingEvent
    {
    }

    public class WaferStateChangedEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }

        public WaferState State { get; set; }
    }

    public class WaferTransferErrorEvent : SubstrateTrackingEvent
    {
        public string Message { get; set; } = "";
    }

    public class WaferTransferEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }

        public WaferLocation From { get; set; }

        public WaferLocation To { get; set; }
    }

    public class WaferSwapEvent : SubstrateTrackingEvent
    {
        public int FoupIn { get; set; }

        public int SlotIn { get; set; }

        public WaferLocation LocationOut { get; set; }

        public int FoupOut { get; set; }

        public int SlotOut { get; set; }

        public WaferLocation LocationIn { get; set; }
    }

    public class ManuallySetLocationEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }

        public WaferLocation Location { get; set; }

        public bool IsDelete { get; set; }
    }

    public class ManuallyCreateWaferEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }
    }

    public class ManuallyDeleteWaferEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }
    }


    public class ManuallyModifyWaferEvent : SubstrateTrackingEvent
    {
        public int OldFoup { get; set; }

        public int OldSlot { get; set; }

        public int NewFoup { get; set; }

        public int NewSlot { get; set; }

        public WaferLocation Location { get; set; }
    }

    public enum WaferStatus
    {
        Empty,
        Processing,
        Loaded,
        Cleaned,
        Error
    }

    public enum WaferLocation
    {
        LoadPort,
        ProcessChamber,
        CleanRoom
    }

    public class WaferState
    {
        public WaferStatus State { get; set; }
    }
}
